package com.xishu.controller;

import com.xishu.annotation.valid.Admin;
import com.xishu.bo.HomeReport;
import com.xishu.bo.ReportBo;
import com.xishu.bo.response.Report;
import com.xishu.bo.shop.ShopReport;
import com.xishu.entity.order.Order;
import com.xishu.entity.order.OrderItem;
import com.xishu.entity.plat.CachePlatReport;
import com.xishu.entity.plat.DayReport;
import com.xishu.entity.plat.ReportData;
import com.xishu.entity.shop.Shop;
import com.xishu.report.CacheReportService;
import com.xishu.response.ResponseData;
import com.xishu.response.ResponseStatus;
import com.xishu.response.VerifyUtil;
import com.xishu.service.*;
import com.xishu.service.order.base.OrderService;
import com.xishu.util.DateUtil;
import com.xishu.util.Tools;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 缓存类报表的查询
 */
@RestController
public class HomeReportController implements Tools {
    private static Logger logger = LoggerFactory.getLogger(HomeReportController.class);
    private OrderService orderService = OrderService.getInstance();
    private ShopService shopService = ShopService.getInstance();
    private CommonService commonService = CommonService.getInstance();
    private ExecutorService threadPool = Executors.newFixedThreadPool(50);

    @Admin
    @PutMapping(value = ("/plat/report/real/time"), produces = ("application/json;charset=UTF-8"))
    @ApiOperation(value = "查询主页实时统计,已本地调试")
    public ResponseData findCacheReport() throws Exception {
        CachePlatReport cachePlatReport = CacheReportService.getInstance().findCachePlatReport();
        //添加查询发送到厨房里面的菜
        DayReport dayReport = DayReportService.getInstance().todayDayReport();
        cachePlatReport.setCountAllOnlineItem(getLong(dayReport.getSendKitchenNumber()));

        return commonService.createResponse(cachePlatReport);
    }

    /**
     * 查询分店的营业数据
     *
     * @param reportBo
     * @return
     */
    @PutMapping(value = ("/shop/report/list"), produces = ("application/json;charset=UTF-8"))
    @ApiOperation(value = "主页的商铺报表--表格形式,已本地调试")
    public ResponseData shopReport(@RequestBody ReportBo reportBo) throws Exception {
        List<Long> shopIdList = reportBo.getShopIdList();
        //必须要有ID
        if (shopIdList.isEmpty()) {
            VerifyUtil.throwError(ResponseStatus.INVALID_PARAMETER);
        }
        long currentTimeMillis = System.currentTimeMillis();

        List<ShopReport> shopReportList =ReportService.getInstance().sumSalesAndCountList(shopIdList, DateUtil.startTimeInDay(currentTimeMillis), currentTimeMillis);
        return commonService.createResponse(shopReportList);
    }

    @PutMapping(value = ("/shop/report/chart"), produces = ("application/json;charset=UTF-8"))
    @ApiOperation(value = "主页的商铺报表折线图,已本地调试")
    public ResponseData shopReportChart(@RequestBody ReportBo reportBo) throws Exception {
        List<Long> shopIdList = reportBo.getShopIdList();

        //必须要有ID
        if (shopIdList.isEmpty()) {
            VerifyUtil.throwError(ResponseStatus.INVALID_PARAMETER);
        }

        long currentTimeMillis = System.currentTimeMillis();
        List<ShopReport> shopReportList = ReportService.getInstance().sumSalesList(shopIdList, DateUtil.startTimeInDay(currentTimeMillis), currentTimeMillis);
        return commonService.createResponse(shopReportList);
    }

    @Admin
    @PutMapping(value = ("/plat/report"), produces = ("application/json;charset=UTF-8"))
    @ApiOperation(value = "查询主页的报表，带拆线图,已本地调试")
    public ResponseData findReport(@RequestBody ReportData reportData) throws Exception {
        int type = reportData.getType();
        VerifyUtil.verify(() -> reportData.getStartCreateTime() != null);
        VerifyUtil.verify(() -> reportData.getEndCreateTime() != null);
        VerifyUtil.verify(() -> type > 0);

        CacheReportService cacheReportService = CacheReportService.getInstance();
        List<Report> reportList = cacheReportService.commonReport(reportData);
        return commonService.createResponse(reportList);
    }

    @ApiOperation(value = "首页新增报表，销售额，支付方式，菜品，流量，客单价统计,参数传shopIdList")
    @PutMapping(value = ("/shop/home/report"), produces = ("application/json;charset=UTF-8"))
    public ResponseData findOrderPayTypePersonReport(@RequestBody ReportBo reportBo) throws Exception {
        CommonService commonService = CommonService.getInstance();
        List<Long> shopIdList = reportBo.getShopIdList();
        VerifyUtil.verify(() -> isNotEmpty(shopIdList));

        HomeReport homeReport = new HomeReport();
        ReportService reportService = ReportService.getInstance();
        long currentTimeMillis = System.currentTimeMillis();
        long todayStartTime = DateUtil.startTimeInDay(currentTimeMillis);
        long todayEndTime = DateUtil.endTimeInDay(currentTimeMillis);
        //当日的订单量
        Future<Double> todayOrderPay = this.threadPool.submit(() -> {
            return reportService.sumTotal(shopIdList, todayStartTime, todayEndTime);
        });
        //当日的订单平均值
        Future<Double> todayOrderPayAvg = this.threadPool.submit(() -> {
            return reportService.avgOrder(shopIdList, todayStartTime, todayEndTime, 1);
        });
        //过去一周的平均值
        Future<Double> lastWeekOrderPayAvg = this.threadPool.submit(() -> {
            return reportService.avgOrder(shopIdList, todayStartTime - DateUtil.ONE_DAY * 7, todayStartTime, 7);
        });
        //过去4周的平均值
        Future<Double> last4WeekOrderPayAvg = this.threadPool.submit(() -> {
            return reportService.avgOrder(shopIdList, todayStartTime - DateUtil.ONE_DAY * 28, todayStartTime, 28);
        });
        //过去6个月的平均值,6个月平均180
        Future<Double> last6MonthOrderPayAvg = this.threadPool.submit(() -> {
            return reportService.avgOrder(shopIdList, todayStartTime - DateUtil.ONE_DAY * 180, todayStartTime, 180);
        });
        //当日完成支付的订单量，按照父订单来统计
        Future<Integer> completeOrderNumber = this.threadPool.submit(() -> {
            return reportService.countCompleteParentOrder(shopIdList, todayStartTime, todayEndTime);
        });
        //支付方式TOP3
        Future<List<Report>> top3PayType = this.threadPool.submit(() -> {
            return reportService.top3PayType(shopIdList, todayStartTime, todayEndTime);
        });
        //其它支付方式
        Future<Double> totalPayType = this.threadPool.submit(() -> {
            return reportService.totalPayType(shopIdList, todayStartTime, todayEndTime);
        });

        Future<List<Order>> findAllPayedOrder = this.threadPool.submit(() -> {
            return reportService.findAllPayedOrder(shopIdList, todayStartTime, todayEndTime);
        });

        //当日菜品的top5
        Future<List<OrderItem>> Top5Item = this.threadPool.submit(() -> {
            return reportService.top5Item(findAllPayedOrder.get());
        });

        //当日品类的top5
        Future<List<OrderItem>> Top5Catalog = this.threadPool.submit(() -> {
            return reportService.top5catalog(findAllPayedOrder.get());
        });

        //过去30天的客流量
        Future<Integer> last30daysPerson = this.threadPool.submit(() -> {
            return reportService.sumPerson(shopIdList, currentTimeMillis - DateUtil.ONE_DAY * 30, currentTimeMillis);
        });

        //过去30天平均客单价
        Future<Double> last30daysAvgPersonCost = this.threadPool.submit(() -> {
            return reportService.avgPersonCost(shopIdList, currentTimeMillis - DateUtil.ONE_DAY * 30, currentTimeMillis);
        });

        //当日的订单量
        homeReport.setTodayOrderPay(todayOrderPay.get());
        //当日的订单平均值
        homeReport.setTodayOrderPayAvg(todayOrderPayAvg.get());
        //过去一周的平均值
        homeReport.setLastWeekOrderPayAvg(lastWeekOrderPayAvg.get());
        //过去4周的平均值
        homeReport.setLast4WeekOrderPayAvg(last4WeekOrderPayAvg.get());
        //过去6个月的平均值,6个月平均180
        homeReport.setLast6MonthOrderPayAvg(last6MonthOrderPayAvg.get());
        //当日完成支付的订单量，按照父订单来统计
        homeReport.setCompleteOrderNumber(completeOrderNumber.get());
        //支付方式TOP3
        homeReport.setTop3PayType(top3PayType.get());
        //其它支付方式
        homeReport.setOtherPayType(totalPayType.get() - top3PayType.get().stream().mapToDouble(p -> p.getValue()).sum());
        //当日菜品的top5
        homeReport.setTop5Item(Top5Item.get());
        //当日品类的top5
        homeReport.setTop5Catalog(Top5Catalog.get());
        //过去30天的客流量
        homeReport.setLast30daysPerson(last30daysPerson.get());
        //过去30天平均客单价
        homeReport.setLast30daysAvgPersonCost(last30daysAvgPersonCost.get());

        return commonService.createResponse(homeReport);
    }

    @ApiOperation(value = "首页星期几的平均值")
    @PutMapping(value = ("/shop/home/report/week/avg"), produces = ("application/json;charset=UTF-8"))
    public ResponseData weekEveryDay(@RequestBody ReportBo reportBo) throws Exception {
        List<Report> reportList = ReportService.getInstance().weekEveryDay(reportBo);
        return commonService.createResponse(reportList);
    }

    @ApiOperation(value = "首页一天小时的平均值")
    @PutMapping(value = ("/shop/home/report/one/day/hour/avg"), produces = ("application/json;charset=UTF-8"))
    public ResponseData hourOneDay(@RequestBody ReportBo reportBo) throws Exception {
        List<Report> reportList = ReportService.getInstance().hourOneDay(reportBo);
        return commonService.createResponse(reportList);

    }

}
